<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>流式聊天机器人</title>
    <!-- Markdown解析库 -->
    <script src="https://cdn.jsdelivr.net/npm/marked@9.1.6/marked.min.js"></script>
    <!-- 代码高亮库 -->
    <script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-core.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/plugins/autoloader/prism-autoloader.min.js"></script>
    <link href="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/themes/prism.min.css" rel="stylesheet">
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
        }

        .chat-container {
            width: 90%;
            max-width: 800px;
            height: 80vh;
            background: white;
            border-radius: 20px;
            box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
            display: flex;
            flex-direction: column;
            overflow: hidden;
        }

        .chat-header {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            padding: 20px;
            text-align: center;
            font-size: 1.5em;
            font-weight: bold;
        }

        .chat-messages {
            flex: 1;
            padding: 20px;
            overflow-y: auto;
            background: #f8f9fa;
        }

        .message {
            margin-bottom: 15px;
            display: flex;
            align-items: flex-start;
            position: relative;
        }

        .message.user {
            justify-content: flex-end;
        }

        .message-content {
            max-width: 70%;
            padding: 12px 16px;
            border-radius: 18px;
            word-wrap: break-word;
            line-height: 1.4;
        }

        .message.user .message-content {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
        }

        .message.bot .message-content {
            background: white;
            border: 1px solid #e1e5e9;
            color: #333;
        }

        .message.bot.streaming .message-content {
            border-color: #667eea;
            box-shadow: 0 0 10px rgba(102, 126, 234, 0.2);
        }

        .chat-input {
            padding: 20px;
            background: white;
            border-top: 1px solid #e1e5e9;
            display: flex;
            gap: 10px;
        }

        .input-field {
            flex: 1;
            padding: 12px 16px;
            border: 2px solid #e1e5e9;
            border-radius: 25px;
            outline: none;
            font-size: 16px;
            transition: border-color 0.3s;
        }

        .input-field:focus {
            border-color: #667eea;
        }

        .send-button {
            padding: 12px 24px;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            border: none;
            border-radius: 25px;
            cursor: pointer;
            font-size: 16px;
            font-weight: bold;
            transition: transform 0.2s;
        }

        .send-button:hover {
            transform: translateY(-2px);
        }

        .send-button:disabled {
            opacity: 0.6;
            cursor: not-allowed;
            transform: none;
        }

        .typing-indicator {
            display: none;
            color: #666;
            font-style: italic;
            margin-left: 10px;
        }

        .typing-indicator.show {
            display: inline;
        }

        .cursor {
            animation: blink 1s infinite;
        }

        @keyframes blink {

            0%,
            50% {
                opacity: 1;
            }

            51%,
            100% {
                opacity: 0;
            }
        }

        .connection-status {
            position: absolute;
            top: 10px;
            right: 10px;
            padding: 5px 10px;
            border-radius: 15px;
            font-size: 12px;
            font-weight: bold;
        }

        .connection-status.connected {
            background: #4CAF50;
            color: white;
        }

        .connection-status.disconnected {
            background: #f44336;
            color: white;
        }

        /* Markdown样式 */
        .message-content h1,
        .message-content h2,
        .message-content h3,
        .message-content h4,
        .message-content h5,
        .message-content h6 {
            margin: 16px 0 8px 0;
            font-weight: bold;
            line-height: 1.3;
        }

        .message-content h1 {
            font-size: 1.5em;
        }

        .message-content h2 {
            font-size: 1.3em;
        }

        .message-content h3 {
            font-size: 1.1em;
        }

        .message-content p {
            margin: 8px 0;
            line-height: 1.6;
        }

        .message-content ul,
        .message-content ol {
            margin: 8px 0;
            padding-left: 20px;
        }

        .message-content li {
            margin: 4px 0;
            line-height: 1.5;
        }

        .message-content blockquote {
            margin: 12px 0;
            padding: 8px 16px;
            border-left: 4px solid #667eea;
            background: rgba(102, 126, 234, 0.1);
            font-style: italic;
        }

        .message-content code {
            background: #f1f3f4;
            padding: 2px 6px;
            border-radius: 4px;
            font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
            font-size: 0.9em;
        }

        .message-content pre {
            background: #f8f9fa;
            border: 1px solid #e1e5e9;
            border-radius: 8px;
            padding: 16px;
            margin: 12px 0;
            overflow-x: auto;
            position: relative;
        }

        .message-content pre code {
            background: none;
            padding: 0;
            border-radius: 0;
            font-size: 0.85em;
            line-height: 1.4;
        }

        .message-content table {
            border-collapse: collapse;
            width: 100%;
            margin: 12px 0;
            font-size: 0.9em;
        }

        .message-content th,
        .message-content td {
            border: 1px solid #e1e5e9;
            padding: 8px 12px;
            text-align: left;
        }

        .message-content th {
            background: #f8f9fa;
            font-weight: bold;
        }

        .message-content a {
            color: #667eea;
            text-decoration: none;
        }

        .message-content a:hover {
            text-decoration: underline;
        }

        .message-content strong {
            font-weight: bold;
        }

        .message-content em {
            font-style: italic;
        }

        .message-content hr {
            border: none;
            border-top: 1px solid #e1e5e9;
            margin: 16px 0;
        }

        /* 代码块复制按钮 */
        .code-block-wrapper {
            position: relative;
        }

        .copy-button {
            position: absolute;
            top: 8px;
            right: 8px;
            background: #667eea;
            color: white;
            border: none;
            border-radius: 4px;
            padding: 4px 8px;
            font-size: 12px;
            cursor: pointer;
            opacity: 0.7;
            transition: opacity 0.2s;
        }

        .copy-button:hover {
            opacity: 1;
        }

        .copy-button.copied {
            background: #4CAF50;
        }

        /* 更多功能按钮样式 */
        .more-actions {
            position: absolute;
            bottom: 8px;
            right: 8px;
            opacity: 0;
            transition: opacity 0.2s;
        }

        .message.bot:hover .more-actions {
            opacity: 1;
        }

        .more-button {
            background: #667eea;
            color: white;
            border: none;
            border-radius: 50%;
            width: 24px;
            height: 24px;
            cursor: pointer;
            font-size: 12px;
            display: flex;
            align-items: center;
            justify-content: center;
            position: relative;
        }

        .more-button:hover {
            background: #5a67d8;
        }

        .dropdown-menu {
            position: absolute;
            bottom: 100%;
            right: 0;
            background: white;
            border: 1px solid #e1e5e9;
            border-radius: 8px;
            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
            min-width: 150px;
            z-index: 1000;
            display: none;
            margin-bottom: 4px;
        }

        .dropdown-menu.show {
            display: block;
        }

        .dropdown-item {
            padding: 8px 12px;
            cursor: pointer;
            border: none;
            background: none;
            width: 100%;
            text-align: left;
            font-size: 14px;
            color: #333;
            display: flex;
            align-items: center;
            gap: 8px;
        }

        .dropdown-item:hover {
            background: #f8f9fa;
        }

        .dropdown-item:first-child {
            border-radius: 8px 8px 0 0;
        }

        .dropdown-item:last-child {
            border-radius: 0 0 8px 8px;
        }

        /* 加载状态 */
        .loading {
            opacity: 0.6;
            pointer-events: none;
        }

        .loading::after {
            content: '';
            position: absolute;
            top: 50%;
            left: 50%;
            width: 16px;
            height: 16px;
            margin: -8px 0 0 -8px;
            border: 2px solid #667eea;
            border-radius: 50%;
            border-top-color: transparent;
            animation: spin 1s linear infinite;
        }

        @keyframes spin {
            to {
                transform: rotate(360deg);
            }
        }

        /* 通知样式 */
        .notification {
            position: fixed;
            top: 20px;
            right: 20px;
            background: #4CAF50;
            color: white;
            padding: 12px 20px;
            border-radius: 8px;
            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
            z-index: 2000;
            transform: translateX(100%);
            transition: transform 0.3s ease;
        }

        .notification.show {
            transform: translateX(0);
        }

        .notification.error {
            background: #f44336;
        }

        /* 回到底部按钮 */
        .scroll-to-bottom {
            position: absolute;
            bottom: 80px;
            right: 20px;
            background: #667eea;
            color: white;
            border: none;
            border-radius: 50%;
            width: 48px;
            height: 48px;
            cursor: pointer;
            font-size: 18px;
            box-shadow: 0 4px 12px rgba(102, 126, 234, 0.3);
            display: none;
            align-items: center;
            justify-content: center;
            transition: all 0.3s ease;
            z-index: 100;
        }

        .scroll-to-bottom.show {
            display: flex;
        }

        .scroll-to-bottom:hover {
            background: #5a67d8;
            transform: translateY(-2px);
        }

        .scroll-to-bottom::before {
            content: '↓';
        }
    </style>
</head>

<body>
    <div class="chat-container">
        <div class="chat-header">
            🤖 流式聊天机器人
            <div class="connection-status" id="connectionStatus">连接中...</div>
        </div>
        <div class="chat-messages" id="chatMessages">
            <div class="message bot">
                <div class="message-content">
                    你好！我是你的AI助手，有什么可以帮助你的吗？
                </div>
            </div>
            <button class="scroll-to-bottom" id="scrollToBottomBtn" title="回到底部"></button>
        </div>
        <div class="chat-input">
            <input type="text" class="input-field" id="messageInput" placeholder="输入你的消息..." maxlength="1000">
            <button class="send-button" id="sendButton">发送</button>
        </div>
    </div>

    <script>
        class StreamingChatBot {
            constructor() {
                this.ws = null;
                this.isConnected = false;
                this.currentBotMessage = null;
                this.currentBotText = '';
                this.isStreaming = false;
                this.autoScroll = true; // 自动滚动标志
                this.scrollTimeout = null; // 滚动超时定时器

                this.chatMessages = document.getElementById('chatMessages');
                this.messageInput = document.getElementById('messageInput');
                this.sendButton = document.getElementById('sendButton');
                this.connectionStatus = document.getElementById('connectionStatus');
                this.scrollToBottomBtn = document.getElementById('scrollToBottomBtn');

                this.init();
                this.setupMarkdown();
                this.setupScrollDetection();
            }

            setupMarkdown() {
                // 配置marked选项
                if (typeof marked !== 'undefined') {
                    marked.setOptions({
                        highlight: function (code, lang) {
                            if (typeof Prism !== 'undefined' && lang && Prism.languages[lang]) {
                                return Prism.highlight(code, Prism.languages[lang], lang);
                            }
                            return code;
                        },
                        breaks: true,
                        gfm: true
                    });
                }
            }

            init() {
                this.connect();
                this.bindEvents();
            }

            setupScrollDetection() {
                this.chatMessages.addEventListener('scroll', () => {
                    // 检查是否滚动到底部
                    const { scrollTop, scrollHeight, clientHeight } = this.chatMessages;
                    const isAtBottom = scrollTop + clientHeight >= scrollHeight - 10; // 10px容差

                    if (isAtBottom) {
                        // 如果滚动到底部，恢复自动滚动并隐藏按钮
                        this.autoScroll = true;
                        this.scrollToBottomBtn.classList.remove('show');
                    } else if (this.isStreaming) {
                        // 如果正在流式输出且用户主动滚动，停止自动滚动并显示按钮
                        this.autoScroll = false;
                        this.scrollToBottomBtn.classList.add('show');
                    }
                });

                // 监听鼠标滚轮事件
                this.chatMessages.addEventListener('wheel', (e) => {
                    if (this.isStreaming && e.deltaY < 0) {
                        // 向上滚动时停止自动滚动并显示按钮
                        this.autoScroll = false;
                        this.scrollToBottomBtn.classList.add('show');
                    }
                });

                // 回到底部按钮点击事件
                this.scrollToBottomBtn.addEventListener('click', () => {
                    this.autoScroll = true;
                    this.scrollToBottomBtn.classList.remove('show');
                    this.chatMessages.scrollTop = this.chatMessages.scrollHeight;
                });
            }

            scrollToBottom() {
                if (this.autoScroll) {
                    this.chatMessages.scrollTop = this.chatMessages.scrollHeight;
                }
            }

            connect() {
                const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
                const wsUrl = `${protocol}//${window.location.host}/ws`;

                this.ws = new WebSocket(wsUrl);

                this.ws.onopen = () => {
                    this.isConnected = true;
                    this.updateConnectionStatus('connected', '已连接');
                    console.log('WebSocket连接已建立');
                };

                this.ws.onmessage = (event) => {
                    this.handleMessage(JSON.parse(event.data));
                };

                this.ws.onclose = () => {
                    this.isConnected = false;
                    this.updateConnectionStatus('disconnected', '连接断开');
                    console.log('WebSocket连接已关闭');
                    // 尝试重连
                    setTimeout(() => this.connect(), 3000);
                };

                this.ws.onerror = (error) => {
                    console.error('WebSocket错误:', error);
                    this.updateConnectionStatus('disconnected', '连接错误');
                };
            }

            updateConnectionStatus(status, text) {
                this.connectionStatus.className = `connection-status ${status}`;
                this.connectionStatus.textContent = text;
            }

            bindEvents() {
                this.sendButton.addEventListener('click', () => this.sendMessage());

                this.messageInput.addEventListener('keypress', (e) => {
                    if (e.key === 'Enter' && !e.shiftKey) {
                        e.preventDefault();
                        this.sendMessage();
                    }
                });
            }

            sendMessage() {
                const message = this.messageInput.value.trim();
                if (!message || !this.isConnected || this.isStreaming) return;

                // 显示用户消息
                this.addMessage('user', message);

                // 发送消息到服务器
                this.ws.send(JSON.stringify({ message }));

                // 清空输入框
                this.messageInput.value = '';
                this.sendButton.disabled = true;
                this.isStreaming = true;
            }

            handleMessage(data) {
                switch (data.type) {
                    case 'start':
                        this.startBotMessage();
                        break;
                    case 'stream':
                        this.appendToBotMessage(data.chunk);
                        break;
                    case 'end':
                        this.endBotMessage();
                        break;
                    case 'error':
                        this.addMessage('bot', data.message);
                        this.endBotMessage();
                        break;
                }
            }

            startBotMessage() {
                const messageDiv = document.createElement('div');
                messageDiv.className = 'message bot streaming';

                const contentDiv = document.createElement('div');
                contentDiv.className = 'message-content';
                contentDiv.innerHTML = '<span class="cursor">|</span>';

                messageDiv.appendChild(contentDiv);
                this.chatMessages.appendChild(messageDiv);

                // 开始新的流式输出时，重新启用自动滚动并隐藏按钮
                this.autoScroll = true;
                this.scrollToBottomBtn.classList.remove('show');
                this.scrollToBottom();

                this.currentBotMessage = contentDiv;
                this.currentBotText = '';
            }

            appendToBotMessage(chunk) {
                if (this.currentBotMessage) {
                    this.currentBotText += chunk;

                    // 实时渲染Markdown
                    let renderedHtml = '';
                    if (typeof marked !== 'undefined') {
                        try {
                            renderedHtml = marked.parse(this.currentBotText);
                        } catch (e) {
                            renderedHtml = this.currentBotText.replace(/\n/g, '<br>');
                        }
                    } else {
                        renderedHtml = this.currentBotText.replace(/\n/g, '<br>');
                    }

                    this.currentBotMessage.innerHTML = renderedHtml + '<span class="cursor">|</span>';
                    this.addCopyButtonsToCodeBlocks();

                    // 只有在自动滚动启用时才滚动到底部
                    this.scrollToBottom();
                }
            }

            endBotMessage() {
                if (this.currentBotMessage) {
                    // 最终渲染Markdown
                    let finalHtml = '';
                    if (typeof marked !== 'undefined') {
                        try {
                            finalHtml = marked.parse(this.currentBotText);
                        } catch (e) {
                            finalHtml = this.currentBotText.replace(/\n/g, '<br>');
                        }
                    } else {
                        finalHtml = this.currentBotText.replace(/\n/g, '<br>');
                    }

                    this.currentBotMessage.innerHTML = finalHtml;
                    this.addCopyButtonsToCodeBlocks();
                    this.currentBotMessage.parentElement.classList.remove('streaming');

                    // 添加更多功能按钮
                    this.addMoreActionsButton(this.currentBotMessage.parentElement, this.currentBotText);

                    // 高亮代码块
                    if (typeof Prism !== 'undefined') {
                        Prism.highlightAllUnder(this.currentBotMessage);
                    }
                }

                this.currentBotMessage = null;
                this.currentBotText = '';
                this.sendButton.disabled = false;
                this.isStreaming = false;
            }

            addMessage(sender, content) {
                const messageDiv = document.createElement('div');
                messageDiv.className = `message ${sender}`;

                const contentDiv = document.createElement('div');
                contentDiv.className = 'message-content';

                if (sender === 'bot' && typeof marked !== 'undefined') {
                    try {
                        contentDiv.innerHTML = marked.parse(content);
                        this.addCopyButtonsToCodeBlocks(contentDiv);
                        // 添加更多功能按钮
                        this.addMoreActionsButton(messageDiv, content);
                        // 高亮代码块
                        if (typeof Prism !== 'undefined') {
                            Prism.highlightAllUnder(contentDiv);
                        }
                    } catch (e) {
                        contentDiv.textContent = content;
                    }
                } else {
                    contentDiv.textContent = content;
                }

                messageDiv.appendChild(contentDiv);
                this.chatMessages.appendChild(messageDiv);

                // 用户发送消息时总是滚动到底部并启用自动滚动
                if (sender === 'user') {
                    this.autoScroll = true;
                }
                this.scrollToBottom();
            }

            addCopyButtonsToCodeBlocks(container = this.currentBotMessage) {
                if (!container) return;

                const codeBlocks = container.querySelectorAll('pre code');
                codeBlocks.forEach(codeBlock => {
                    const pre = codeBlock.parentElement;

                    // 避免重复添加按钮
                    if (pre.querySelector('.copy-button')) return;

                    // 创建包装器
                    if (!pre.classList.contains('code-block-wrapper')) {
                        pre.classList.add('code-block-wrapper');
                    }

                    // 创建复制按钮
                    const copyButton = document.createElement('button');
                    copyButton.className = 'copy-button';
                    copyButton.textContent = '复制';
                    copyButton.onclick = () => this.copyCode(codeBlock, copyButton);

                    pre.appendChild(copyButton);
                });
            }

            async copyCode(codeBlock, button) {
                const originalText = button.textContent;
                try {
                    const code = codeBlock.textContent;
                    
                    // 检查是否支持现代剪贴板API
                    if (navigator.clipboard && window.isSecureContext) {
                        await navigator.clipboard.writeText(code);
                    } else {
                        // 降级到传统方法
                        this.fallbackCopyText(code);
                    }

                    button.textContent = '已复制';
                    button.classList.add('copied');

                    setTimeout(() => {
                        button.textContent = originalText;
                        button.classList.remove('copied');
                    }, 2000);
                } catch (err) {
                    console.error('复制失败:', err);
                    // 尝试降级方法
                    try {
                        this.fallbackCopyText(codeBlock.textContent);
                        button.textContent = '已复制';
                        button.classList.add('copied');
                        setTimeout(() => {
                            button.textContent = originalText;
                            button.classList.remove('copied');
                        }, 2000);
                    } catch (fallbackErr) {
                        console.error('降级复制也失败:', fallbackErr);
                        button.textContent = '复制失败';
                        setTimeout(() => {
                            button.textContent = originalText;
                        }, 2000);
                    }
                }
            }

            addMoreActionsButton(messageDiv, markdownContent) {
                // 避免重复添加
                if (messageDiv.querySelector('.more-actions')) return;

                // 获取对应的用户消息
                const userQuestion = this.getUserQuestionForBotMessage(messageDiv);

                const moreActions = document.createElement('div');
                moreActions.className = 'more-actions';

                const moreButton = document.createElement('button');
                moreButton.className = 'more-button';
                moreButton.innerHTML = '⋯';
                moreButton.title = '更多功能';

                const dropdownMenu = document.createElement('div');
                dropdownMenu.className = 'dropdown-menu';

                // 转为DOCX功能
                const docxItem = document.createElement('button');
                docxItem.className = 'dropdown-item';
                docxItem.innerHTML = '📄 转为DOCX';
                docxItem.onclick = () => this.convertToFormat(markdownContent, dropdownMenu, 'docx', userQuestion);

                // 复制Markdown功能
                const copyMarkdownItem = document.createElement('button');
                copyMarkdownItem.className = 'dropdown-item';
                copyMarkdownItem.innerHTML = '📋 复制原文';
                copyMarkdownItem.onclick = () => this.copyMarkdown(markdownContent, dropdownMenu);

                dropdownMenu.appendChild(docxItem);

                // 检查是否支持PDF转换
                this.checkPdfSupport().then(supported => {
                    if (supported) {
                        const pdfItem = document.createElement('button');
                        pdfItem.className = 'dropdown-item';
                        pdfItem.innerHTML = '📕 转为PDF';
                        pdfItem.onclick = () => this.convertToFormat(markdownContent, dropdownMenu, 'pdf', userQuestion);
                        dropdownMenu.insertBefore(pdfItem, copyMarkdownItem);
                    }
                });

                dropdownMenu.appendChild(copyMarkdownItem);

                moreButton.onclick = (e) => {
                    e.stopPropagation();
                    // 关闭其他下拉菜单
                    document.querySelectorAll('.dropdown-menu.show').forEach(menu => {
                        if (menu !== dropdownMenu) {
                            menu.classList.remove('show');
                        }
                    });
                    dropdownMenu.classList.toggle('show');
                };

                moreActions.appendChild(moreButton);
                moreActions.appendChild(dropdownMenu);
                messageDiv.appendChild(moreActions);

                // 点击其他地方关闭下拉菜单
                document.addEventListener('click', (e) => {
                    if (!moreActions.contains(e.target)) {
                        dropdownMenu.classList.remove('show');
                    }
                });
            }

            async copyMarkdown(markdownContent, dropdownMenu) {
                try {
                    // 检查是否支持现代剪贴板API
                    if (navigator.clipboard && window.isSecureContext) {
                        await navigator.clipboard.writeText(markdownContent);
                        this.showNotification('Markdown内容已复制到剪贴板', 'success');
                    } else {
                        // 降级到传统方法
                        this.fallbackCopyText(markdownContent);
                        this.showNotification('Markdown内容已复制到剪贴板', 'success');
                    }
                    dropdownMenu.classList.remove('show');
                } catch (err) {
                    console.error('复制失败:', err);
                    // 尝试降级方法
                    try {
                        this.fallbackCopyText(markdownContent);
                        this.showNotification('Markdown内容已复制到剪贴板', 'success');
                        dropdownMenu.classList.remove('show');
                    } catch (fallbackErr) {
                        console.error('降级复制也失败:', fallbackErr);
                        this.showNotification('复制失败，请手动选择文本复制', 'error');
                    }
                }
            }

            fallbackCopyText(text) {
                // 创建临时文本区域
                const textArea = document.createElement('textarea');
                textArea.value = text;
                textArea.style.position = 'fixed';
                textArea.style.left = '-999999px';
                textArea.style.top = '-999999px';
                document.body.appendChild(textArea);
                textArea.focus();
                textArea.select();
                
                try {
                    const successful = document.execCommand('copy');
                    if (!successful) {
                        throw new Error('execCommand copy failed');
                    }
                } finally {
                    document.body.removeChild(textArea);
                }
            }

            getUserQuestionForBotMessage(botMessageDiv) {
                // 查找当前机器人消息前面最近的用户消息
                let currentElement = botMessageDiv.previousElementSibling;
                while (currentElement) {
                    if (currentElement.classList.contains('message') && currentElement.classList.contains('user')) {
                        const messageContent = currentElement.querySelector('.message-content');
                        return messageContent ? messageContent.textContent.trim() : '';
                    }
                    currentElement = currentElement.previousElementSibling;
                }
                return '';
            }

            async convertToFormat(markdownContent, dropdownMenu, format, userQuestion = '') {
                const targetItem = format === 'docx' ?
                    dropdownMenu.querySelector('.dropdown-item:nth-child(1)') :
                    dropdownMenu.querySelector('.dropdown-item:nth-child(2)');
                const originalText = targetItem.innerHTML;

                try {
                    // 显示加载状态
                    targetItem.innerHTML = '🔄 转换中...';
                    targetItem.classList.add('loading');

                    const endpoint = format === 'docx' ? '/convert-to-docx' : '/convert-to-pdf';
                    const response = await fetch(endpoint, {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/json',
                        },
                        body: JSON.stringify({
                            markdown_text: markdownContent,
                            title: 'AI对话导出',
                            user_question: userQuestion
                        })
                    });

                    if (!response.ok) {
                        const errorData = await response.json().catch(() => ({}));
                        throw new Error(errorData.detail || `转换失败: ${response.status}`);
                    }

                    const result = await response.json();

                    if (result.success) {
                        // 触发下载
                        const link = document.createElement('a');
                        link.href = result.download_url;
                        link.download = result.filename;
                        document.body.appendChild(link);
                        link.click();
                        document.body.removeChild(link);

                        // 显示转换器信息
                        const formatName = format.toUpperCase();
                        const converterInfo = result.converter ? ` (使用${result.converter})` : '';
                        this.showNotification(`${formatName}文档已生成，正在下载...${converterInfo}`, 'success');
                    } else {
                        throw new Error('转换失败');
                    }
                } catch (error) {
                    console.error('转换失败:', error);
                    // 根据错误类型提供不同的提示
                    if (error.message.includes('pandoc') || error.message.includes('Pandoc')) {
                        this.showNotification('转换失败：请安装Pandoc以获得更好的DOCX转换效果', 'error');
                    } else if (format === 'pdf' && (error.message.includes('Chrome') || error.message.includes('Chromium'))) {
                        this.showNotification('PDF转换需要Chrome或Chromium浏览器', 'error');
                    } else {
                        this.showNotification(`${format.toUpperCase()}转换失败，请稍后重试`, 'error');
                    }
                } finally {
                    // 恢复按钮状态
                    targetItem.innerHTML = originalText;
                    targetItem.classList.remove('loading');
                    dropdownMenu.classList.remove('show');
                }
            }

            async checkPdfSupport() {
                try {
                    const response = await fetch('/converter-status');
                    const status = await response.json();
                    return status.pdf_method !== '不可用';
                } catch (error) {
                    console.error('检查PDF支持失败:', error);
                    return false;
                }
            }

            showNotification(message, type = 'success') {
                const notification = document.createElement('div');
                notification.className = `notification ${type}`;
                notification.textContent = message;

                document.body.appendChild(notification);

                // 显示通知
                setTimeout(() => {
                    notification.classList.add('show');
                }, 100);

                // 3秒后隐藏
                setTimeout(() => {
                    notification.classList.remove('show');
                    setTimeout(() => {
                        if (document.body.contains(notification)) {
                            document.body.removeChild(notification);
                        }
                    }, 300);
                }, 3000);
            }
        }

        // 初始化聊天机器人
        document.addEventListener('DOMContentLoaded', () => {
            new StreamingChatBot();
        });
    </script>
</body>

</html>